package com.wujian.love.study.thread;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;

/**
 * @ClassName: TestHarness
 * @Description: 闭锁（CountDownLatch）是 java.util.concurrent 包下的一种同步工具类。
 * 闭锁可以用来确保某些活动直到其他活动都完成后才执行。
 * @Author: wuj
 * @Date: 2021-03-08 08:50
 **/
public class TestHarness {

    public static void main(String[] args) throws InterruptedException {

        long l = timeTasks(5, new Runnable() {
            @Override
            public void run() {

            }
        });
        System.out.println(l);
    }

    public static long timeTasks(int nThreads, final Runnable task) throws InterruptedException {

        //构造方法，创建一个值为count 的计数器。
        final CountDownLatch startGate = new CountDownLatch(1);

        final CountDownLatch endGate = new CountDownLatch(nThreads);

        for (int i = 0; i < nThreads; i++) {

            Thread t = new Thread() {

                public void run() {
                    try {
                        //阻塞当前线程，将当前线程加入阻塞队列
                        startGate.await();
                        try {
                            task.run();
                            System.out.println("执行run方法");
                        } finally {
                            System.out.println("endCate .countDown 方法");
                            endGate.countDown();

                        }
                    } catch (InterruptedException ignored) {

                    }


                }
            };
            t.start();
        }

        long start = System.nanoTime();
        System.out.println("start:" + start);
        //对计数器进行递减1操作，当计数器递减至0时，当前线程会去唤醒阻塞队列里的所有线程。
        startGate.countDown();
        System.out.println("startGate.countDown方法");

        endGate.await();
        System.out.println("执行endGate.await");
        long end = System.nanoTime();
        System.out.println("end:" + end);

        return end - start;
    }
}


class Test {
    //用于聚合所有的统计指标
    private static ConcurrentHashMap map = new ConcurrentHashMap();
    //创建计数器，这里需要统计4个指标
    private static CountDownLatch countDownLatch = new CountDownLatch(4);

    public static void main(String[] args) {

        //记录开始时间
        long startTime = System.currentTimeMillis();

        Thread countUserThread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("正在统计新增用户数量");
                    Thread.sleep(3000);//任务执行需要3秒
                    map.put("userNumber", 1);//保存结果值
                    countDownLatch.countDown();//标记已经完成一个任务
                    System.out.println("统计新增用户数量完毕");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        });
        Thread countOrderThread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("正在统计订单数量");
                    Thread.sleep(3000);//任务执行需要3秒
                    map.put("countOrder", 2);//保存结果值
                    countDownLatch.countDown();//标记已经完成一个任务
                    System.out.println("统计订单数量完毕");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        });

        Thread countGoodsThread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("正在商品销量");
                    Thread.sleep(3000);//任务执行需要3秒
                    map.put("countGoods", 3);//保存结果值
                    countDownLatch.countDown();//标记已经完成一个任务
                    System.out.println("统计商品销量完毕");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        });

        Thread countmoneyThread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("正在总销售额");
                    Thread.sleep(3000);//任务执行需要3秒
                    map.put("countmoney", 4);//保存结果值
                    countDownLatch.countDown();//标记已经完成一个任务
                    System.out.println("统计销售额完毕");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        });
        //启动子线程执行任务
        countUserThread.start();
        countGoodsThread.start();
        countOrderThread.start();
        countmoneyThread.start();

        try {
            //主线程等待所有统计指标执行完毕
            countDownLatch.await();
            //记录结束时间
            long endTime = System.currentTimeMillis();
            System.out.println("------统计指标全部完成--------");
            System.out.println("统计结果为：" + map.toString());
            System.out.println("任务总执行时间为" + (endTime - startTime) / 1000 + "秒");

        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

}
